local _, addon = ...
local playerName = UnitName("player") .. "-" .. GetRealmName()
local player = {}

addon.defaultDB = {
  DBVersion = 1,
  PlayerList = {}
}

-- returns how many hours the server time is ahead of local time
-- convert local time -> server time: add this value
-- convert server time -> local time: subtract this value
function addon:GetServerOffset()
  local serverDate = C_DateAndTime.GetCurrentCalendarTime() -- 1-based starts on Sun
  local serverWeekday, serverMinute, serverHour = serverDate.weekday, serverDate.minute, serverDate.hour
  -- #211: date("%w") is 0-based starts on Sun
  local localWeekday = tonumber(date("%w")) + 1
  local localHour, localMinute = tonumber(date("%H")), tonumber(date("%M"))
  if serverWeekday == (localWeekday + 1) % 7 then -- server is a day ahead
    serverHour = serverHour + 24
  elseif localWeekday == (serverWeekday + 1) % 7 then -- local is a day ahead
    localHour = localHour + 24
  end
  local server = serverHour + serverMinute / 60
  local localT = localHour + localMinute / 60
  local offset = floor((server - localT) * 2 + 0.5) / 2
  return offset
end

function addon:GetRegion()
  if not addon.region then
    local reg
    reg = GetCVar("portal")
    if reg == "public-test" then -- PTR uses US region resets, despite the misleading realm name suffix
      reg = "US"
    end
    if not reg or #reg ~= 2 then
      local gcr = GetCurrentRegion()
      reg = gcr and ({"US", "KR", "EU", "TW", "CN"})[gcr]
    end
    if not reg or #reg ~= 2 then -- other test realms?
      reg = (GetRealmName() or ""):match("%((%a%a)%)")
    end
    reg = reg and reg:upper()
    if reg and #reg == 2 then
      addon.region = reg
    end
  end
  return addon.region
end

function addon:GetNextDailyResetTime()
  local resettime = GetQuestResetTime()
  if
    not resettime or resettime <= 0 or -- ticket 43: can fail during startup
      -- also right after a daylight savings rollover, when it returns negative values >.<
      resettime > 24 * 3600 + 30
   then -- can also be wrong near reset in an instance
    return nil
  end

  return time() + resettime
end

do
  local midnight = {hour = 23, min = 59, sec = 59}
  function addon:GetNextDailySkillResetTime() -- trade skill reset time
    -- this is just a "best guess" because in reality,
    -- different trade skills reset at up to 3 different times
    local rt = addon:GetNextDailyResetTime()
    if not rt then
      return nil
    end
    --local info = date("*t"); print(info.isdst)
    -- Blizzard's ridiculous reset crap:
    -- trade skills ignore daylight savings after the date it changes UNTIL the next restart, then go back to observing it

    return rt
  end
end

function addon:GetNextWeeklyResetTime()
  if not addon.resetDays then
    local region = addon:GetRegion()
    if not region then
      return nil
    end
    addon.resetDays = {}
    addon.resetDays.DLHoffset = 0
    if region == "US" then
      addon.resetDays["2"] = true -- tuesday
      -- ensure oceanic servers over the dateline still reset on tues UTC (wed 1/2 AM server)
      addon.resetDays.DLHoffset = -3
    elseif region == "EU" then
      addon.resetDays["3"] = true -- wednesday
    elseif region == "CN" or region == "KR" or region == "TW" then -- XXX: codes unconfirmed
      addon.resetDays["4"] = true -- thursday
    else
      addon.resetDays["2"] = true -- tuesday?
    end
  end
  local offset = (addon:GetServerOffset() + addon.resetDays.DLHoffset) * 3600
  local nightlyReset = addon:GetNextDailyResetTime()
  if not nightlyReset then
    return nil
  end
  --while date("%A",nightlyReset+offset) ~= WEEKDAY_TUESDAY do
  while not addon.resetDays[date("%w", nightlyReset + offset)] do
    nightlyReset = nightlyReset + 24 * 3600
  end

  return nightlyReset
end

-- 搜索成就ID
function GetStatisticId()
  for _, CategoryId in pairs(GetStatisticsCategoryList()) do
    for i = 1, GetCategoryNumAchievements(CategoryId) do
      local IDNumber, Name = GetAchievementInfo(CategoryId, i)
      if string.find(Name, "麦卡贡") then
        print(Name)
        print(IDNumber)
      end
    end
  end
end

-- 钥石
function RefreshMythicKeyInfo()
  -- 检查钥石
  local mythicKey = {}
  for bagID = 0, 4 do
    for invID = 1, GetContainerNumSlots(bagID) do
      local itemID = GetContainerItemID(bagID, invID)
      if itemID and itemID == 158923 then
        local keyLink = GetContainerItemLink(bagID, invID)
        local KeyInfo = {strsplit(":", keyLink)}
        local mapID = tonumber(KeyInfo[3])
        local mapLevel = tonumber(KeyInfo[4])
        local color
        if KeyInfo[4] == "0" then
          color = select(4, GetItemQualityColor(0))
        elseif mapLevel >= 15 then
          color = select(4, GetItemQualityColor(5))
        elseif mapLevel >= 10 then
          color = select(4, GetItemQualityColor(4))
        elseif mapLevel >= 7 then
          color = select(4, GetItemQualityColor(3))
        elseif mapLevel >= 4 then
          color = select(4, GetItemQualityColor(2))
        else
          -- color = select(4, GetItemQualityColor(1))
          color = "ff000000"
        end
        mythicKey["Dungeons"] = C_ChallengeMode.GetMapUIInfo(mapID)
        mythicKey["Level"] = mapLevel
        mythicKey["Color"] = color
        mythicKey["ResetTime"] = addon:GetNextWeeklyResetTime()
        player["MythicKey"] = mythicKey
      end
    end
  end

  -- 检查本周最佳钥匙
  local mythicKeyBest = {}

  if mythicKeyBest and (mythicKeyBest.ResetTime or 0) < time() then -- dont know weekly reset function will run early or not
    if mythicKeyBest.level and mythicKeyBest.level > 0 then
      mythicKeyBest.LastWeekLevel = mythicKeyBest.level
    end
  end
  mythicKeyBest = mythicKeyBest or {}
  mythicKeyBest["ResetTime"] = addon:GetNextWeeklyResetTime()
  mythicKeyBest["Level"] = C_MythicPlus.GetWeeklyChestRewardLevel()
  mythicKeyBest["WeeklyReward"] = C_MythicPlus.IsWeeklyRewardAvailable()
  player["MythicKeyBest"] = mythicKeyBest

  SingleWolfHelperDB.PlayerList[playerName] = player
end

function RefreshPlayerInfo()
  -- 阵营
  local faction = UnitFactionGroup("player")
  if faction == "Alliance" then
    player["Faction"] = "联盟"
  else
    player["Faction"] = "部落"
  end

  -- 种族
  local race, _ = UnitRace("player")
  player["Race"] = race

  -- 职业
  local LClass, _ = UnitClass("player")
  player["LClass"] = LClass

  -- 等级
  local level = UnitLevel("player")
  player["Level"] = level

  -- 史诗地下城
  player["Dungeons"] = {
    ["Statistic12773"] = GetStatistic(12773), -- 围攻伯拉勒斯
    ["Statistic12745"] = GetStatistic(12745), -- 地渊孢林
    ["Statistic12776"] = GetStatistic(12776), -- 塞塔里斯神庙
    ["Statistic12782"] = GetStatistic(12782), -- 托尔达戈
    ["Statistic12779"] = GetStatistic(12779), -- 暴富矿区
    ["Statistic12785"] = GetStatistic(12785), -- 维克雷斯庄园
    ["Statistic12752"] = GetStatistic(12752), -- 自由镇
    ["Statistic12763"] = GetStatistic(12763), -- 诸王之眠
    ["Statistic12749"] = GetStatistic(12749), -- 阿塔达萨
    ["Statistic12768"] = GetStatistic(12768), -- 风暴神殿
    ["Statistic13620"] = GetStatistic(13620) -- 麦卡贡行动
    -- ["Statistic13620"] = GetStatistic(13620), -- 麦卡贡-车间
    -- ["Statistic13620"] = GetStatistic(13620) -- 麦卡贡-垃圾场
  }

  -- 神器
  local azeriteItemLocation = C_AzeriteItem.FindActiveAzeriteItem()
  if azeriteItemLocation and azeriteItemLocation:IsEquipmentSlot() then
    local xp, totalLevelXP = C_AzeriteItem.GetAzeriteItemXPInfo(azeriteItemLocation)
    local currentLevel = C_AzeriteItem.GetPowerLevel(azeriteItemLocation)
    player["ArtifactLevel"] = currentLevel
    player["ArtifactXP"] = xp / totalLevelXP * 100
  end

  -- 装等
  local IL, ILe = GetAverageItemLevel()
  if IL and tonumber(IL) and tonumber(IL) > 0 then
    local IL, ILe = tonumber(IL), tonumber(ILe)
    player["ILe"] = ILe
    player["IL"] = IL
  end

  SingleWolfHelperDB.PlayerList[playerName] = player
end

local frame = CreateFrame("FRAME")
frame:RegisterEvent("ADDON_LOADED")
frame:RegisterEvent("PLAYER_LOGOUT")
frame:RegisterEvent("BAG_UPDATE")
frame:RegisterEvent("CHALLENGE_MODE_MAPS_UPDATE")
frame:RegisterEvent("CHAT_MSG_WHISPER")

function frame:OnEvent(event, arg1, arg2, arg3)
  if event == "ADDON_LOADED" then
    -- print("ADDON_LOADED")
    SingleWolfHelperDB = SingleWolfHelperDB or addon.defaultDB
    if SingleWolfHelperDB.DBVersion < addon.defaultDB.DBVersion then
      SingleWolfHelperDB = addon.defaultDB
    end
    RefreshPlayerInfo()
    RefreshMythicKeyInfo()
  end

  if event == "PLAYER_LOGOUT" then
    -- print("PLAYER_LOGOUT")
    RefreshPlayerInfo()
  end

  if event == "BAG_UPDATE" then
    -- print("BAG_UPDATE")
    RefreshPlayerInfo()
    RefreshMythicKeyInfo()
  end

  if event == "CHALLENGE_MODE_MAPS_UPDATE" then
    -- print("CHALLENGE_MODE_MAPS_UPDATE")
    RefreshMythicKeyInfo()
  end

  if event == "CHAT_MSG_WHISPER" then
    if arg1 == "123" then
      print(arg2)
      print(arg3)
    end
  end
end
frame:SetScript("OnEvent", frame.OnEvent)

SLASH_SINGLEWOLF1 = "/singlewolf"
function SlashCmdList.SINGLEWOLF(msg)
  print("独狼助手当前版本: " .. addon.defaultDB.DBVersion)
end
